/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2008 the original author or authors.
 */
package com.bluestone.report;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

import com.bluestone.util.Util;

/**
 * ProjectReportDataSource defines the DataSource for the JasperReport.
 * @author <a href="mailto:ming7655@gmail.com">Aaron</a>
 */
public class ProjectReportDataSource implements JRDataSource {
	private String ATTR_PROJECT = "project";

	private String ATTR_TESTSUITE = "testSuite";

	private String ATTR_TESTCASE = "testCase";

	private ProjectReportBean prb;

	private int index = -1;

	public ProjectReportDataSource(ProjectReportBean prb) {
		this.prb = prb;
	}

	public Object getFieldValue(JRField jrField) throws JRException {
		String fieldName = jrField.getName();
		if ("reportId".equals(fieldName)) {
			return Integer.valueOf(index);
		}
		TestCaseReportBean tcrb = prb.getTestCaseReportBean(index);

		if (fieldName.startsWith(this.ATTR_PROJECT)) {
			return this.handlerAttributes(fieldName, prb);
		} else if (fieldName.startsWith(this.ATTR_TESTSUITE)) {
			return this.handlerAttributes(fieldName, tcrb.getParent());
		} else if (fieldName.startsWith(this.ATTR_TESTCASE)) {
			return this.handlerAttributes(fieldName, tcrb);
		}

		return "";
	}

	private Object handlerAttributes(String fieldName, AbstractReportBean prb) {
		try {
			Method[] methods = prb.getClass().getMethods();

			for (int i = 0; i < methods.length; i++) {
				Method tmp = methods[i];
				String methodName = tmp.getName();
				if (methodName.startsWith("get")
						&& fieldName.equalsIgnoreCase(methodName.substring(3))) {
					Object value = tmp.invoke(prb, null);
					return value == null || "null".equals(value) ? "" : value;
				} else if (methodName.equals("getExpAttributes")) {
					HashMap expAttrs = (HashMap) tmp.invoke(prb, null);
					Set keys = expAttrs.keySet();
					Iterator iterator = keys.iterator();
					while (iterator.hasNext()) {
						String key = String.valueOf(iterator.next());
						if (fieldName.equals(key)
								|| fieldName
										.endsWith(AbstractExpAttributeHandler.EXPATTR_TIMECONSUME)
								&& AbstractExpAttributeHandler.EXPATTR_TIMECONSUME
										.equals(key)) {
							Object value = expAttrs.get(key);
							return value == null || "null".equals(value) ? ""
									: value;
						}
					}

				}
			}
		} catch (Exception e) {
			Util.error(e);
		}
		return null;
	}

	public boolean next() throws JRException {
		index++;
		return (index < this.getPrb().getProjectTCCount());
	}

	public ProjectReportBean getPrb() {
		return prb;
	}

	public void setPrb(ProjectReportBean prb) {
		this.prb = prb;
	}
}
